package com.woniuxy.health.commodity.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.health.commodity.dto.GoodsDTO;
import com.woniuxy.health.commodity.dto.MessageDTO;
import com.woniuxy.health.commodity.mapper.GoodsMapper;
import com.woniuxy.health.customer.mapper.UserMapper;
import com.woniuxy.health.model.commodity.Goods;
import com.woniuxy.health.commodity.service.IGoodsService;
import com.woniuxy.health.model.customer.User;
import com.woniuxy.health.vo.GoodsVO;
import com.woniuxy.health.vo.PageVO;
import com.woniuxy.utils.result.Asserts;
import com.woniuxy.utils.result.ResultCodeEnum;
import org.codehaus.jackson.map.ObjectMapper;
import org.elasticsearch.index.query.QueryBuilders;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author woniuxy
 * @since 2023-09-04
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {

    private final GoodsMapper goodsMapper;
    private final ElasticsearchRestTemplate es;
    private final UserMapper userMapper;
    private final RabbitTemplate rabbitTemplate;

    @Value("${spring.mail.username}")
    private String sender;

    @Value("${alibaba.bucket}")
    private String bucket;

    @Value("${alibaba.cloud.oss.endpoint}")
    private String endpoint;

    public GoodsServiceImpl(GoodsMapper goodsMapper, ElasticsearchRestTemplate es, UserMapper userMapper, RabbitTemplate rabbitTemplate){
        this.goodsMapper = goodsMapper;
        this.es = es;
        this.userMapper = userMapper;
        this.rabbitTemplate = rabbitTemplate;
    }

    @Override
    public Page getPageInfo(GoodsDTO goodsDTO) {
        Page<Object> page = Page.of(goodsDTO.getPageNum(), goodsDTO.getPageSize());
        // 设置查询页数
        goodsDTO.setPageNum(goodsDTO.getPageNum() - 1);
        // 查询数据
        Page getPageInfo = goodsMapper.selectGoods(page, goodsDTO);

        List<GoodsVO> records = getPageInfo.getRecords();
        records.forEach(e -> {
            e.setGoodsPhoto("https://" + bucket + "." + endpoint + "/" + e.getBigPhoto().split(";")[0]);
        });

        getPageInfo.setRecords(records);
        return getPageInfo;
    }

    // 批量操作
    @Transactional
    @Override
    public void batchOperate(List<Integer> ids, Byte b) {
        Asserts.fail(ids.size() == 0, ResultCodeEnum.NO_DATA);
        String goodsName = "";
        for (Integer id : ids) {
            Goods goods = goodsMapper.selectById(id);
            goods.setGoodsState(b);
            goodsMapper.updateById(goods);
            goodsName += goods.getGoodsName() + " ";
        }

        // 商品上架后，根据用户状态，推送营销邮件
        if (b == 0){
            List<User> users = userMapper.selectList(null);
            for (User user : users) {
                if (StringUtils.hasLength(user.getUserTel())){
                    MessageDTO messageDTO = new MessageDTO();
                    messageDTO.setFrom(sender);
                    messageDTO.setTo(new String[]{user.getUserTel()});
                    messageDTO.setSubject("[蜗牛运动]温馨提醒：");
                    messageDTO.setText("您所关注的商品：" + goodsName + "已上架，快来抢购吧！！！");
                    try {
                        String jsonStr = JSONUtil.toJsonStr(messageDTO);
                        // 邮件消息推送到邮件队列
                        rabbitTemplate.convertAndSend("fanoutExchange", null, jsonStr);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }

    // 通过es进行查询
    @Override
    public PageVO listByElasticSearch(Pageable page, GoodsDTO goodsDTO) {

        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        // 商品名称
        if (StringUtils.hasLength(goodsDTO.getGoodsName())){
            builder.withQuery(QueryBuilders.multiMatchQuery(goodsDTO.getGoodsName(),
                    "goodsName", "goodsHead",
                    "goodsSubHead", "goodsDetail", "goodsTypeName"));
        }

        // 商品编码
        if (StringUtils.hasLength(goodsDTO.getGoodsCode())){
            builder.withQuery(QueryBuilders.matchQuery("goodsCode",
                    goodsDTO.getGoodsCode()));
        }

        // 商品状态
        if (goodsDTO.getGoodsState() != null){
            builder.withQuery(QueryBuilders.matchQuery("goodsState",
                    goodsDTO.getGoodsState()));
        }

        // 商品分类
        if (goodsDTO.getGoodsTypeId() != null){
            builder.withQuery(QueryBuilders.multiMatchQuery(goodsDTO.getGoodsTypeId(),
                    "parentId", "typeId"));
        }

        builder.withPageable(page);
        SearchHits<GoodsVO> hits = es.search(builder.build(), GoodsVO.class);
        List<GoodsVO> goodsVOS =
                hits.stream().map(e -> e.getContent()).collect(Collectors.toList());

        return new PageVO(hits.getTotalHits(), goodsVOS);
    }
}
